/**
 * 数据源管理工具
 * 提供在 Remote API、Mock 数据、SQLite 本地数据库之间切换的功能
 */

import { API_CONFIG } from '@/config'
import request from '@/utils/request'

// 数据源类型常量
export const DATA_SOURCE_TYPES = {
  REMOTE: 'remote',    // 远程API
  MOCK: 'mock',        // Mock数据
  SQLITE: 'sqlite'     // SQLite本地数据库
}

// 数据源配置
const DATA_SOURCE_CONFIG = {
  [DATA_SOURCE_TYPES.REMOTE]: {
    name: '远程API',
    description: '从服务器获取实时数据',
    icon: 'cloud',
    color: '#3498db',
    requiresNetwork: true,
    persistent: false
  },
  [DATA_SOURCE_TYPES.MOCK]: {
    name: 'Mock数据',
    description: '使用模拟数据进行开发测试',
    icon: 'code',
    color: '#f39c12',
    requiresNetwork: false,
    persistent: false
  },
  [DATA_SOURCE_TYPES.SQLITE]: {
    name: '本地数据库',
    description: '使用SQLite本地存储数据',
    icon: 'database',
    color: '#2ecc71',
    requiresNetwork: false,
    persistent: true
  }
}

class DataSourceManager {
  constructor() {
    this.currentDataSource = this.getCurrentDataSource()
    this.listeners = []
  }

  /**
   * 获取当前数据源
   * @returns {string} 当前数据源类型
   */
  getCurrentDataSource() {
    // 优先从本地存储获取用户设置
    const savedDataSource = uni.getStorageSync('dataSource')
    if (savedDataSource && Object.values(DATA_SOURCE_TYPES).includes(savedDataSource)) {
      return savedDataSource
    }
    
    // 其次从配置文件获取
    if (API_CONFIG.dataSource && Object.values(DATA_SOURCE_TYPES).includes(API_CONFIG.dataSource)) {
      return API_CONFIG.dataSource
    }
    
    // 最后使用默认值
    return DATA_SOURCE_TYPES.REMOTE
  }

  /**
   * 设置数据源
   * @param {string} dataSource 数据源类型
   * @param {boolean} persistent 是否持久化保存
   */
  setDataSource(dataSource, persistent = true) {
    if (!Object.values(DATA_SOURCE_TYPES).includes(dataSource)) {
      throw new Error(`无效的数据源类型: ${dataSource}`)
    }

    const oldDataSource = this.currentDataSource
    this.currentDataSource = dataSource

    // 更新请求管理器配置
    request.setConfig({
      dataSource,
      useMock: dataSource === DATA_SOURCE_TYPES.MOCK
    })

    // 持久化保存
    if (persistent) {
      uni.setStorageSync('dataSource', dataSource)
    }

    // 通知监听器
    this.notifyListeners({
      type: 'dataSourceChanged',
      oldDataSource,
      newDataSource: dataSource,
      config: this.getDataSourceConfig(dataSource)
    })

    console.log(`[DataSource] 切换数据源: ${oldDataSource} -> ${dataSource}`)
  }

  /**
   * 获取数据源配置
   * @param {string} dataSource 数据源类型
   * @returns {object} 数据源配置
   */
  getDataSourceConfig(dataSource = this.currentDataSource) {
    return DATA_SOURCE_CONFIG[dataSource] || null
  }

  /**
   * 获取所有可用的数据源
   * @returns {Array} 数据源列表
   */
  getAvailableDataSources() {
    return Object.keys(DATA_SOURCE_CONFIG).map(type => ({
      type,
      ...DATA_SOURCE_CONFIG[type],
      isCurrent: type === this.currentDataSource
    }))
  }

  /**
   * 检查数据源是否可用
   * @param {string} dataSource 数据源类型
   * @returns {Promise<boolean>} 是否可用
   */
  async checkDataSourceAvailability(dataSource) {
    const config = this.getDataSourceConfig(dataSource)
    if (!config) {
      return false
    }

    try {
      switch (dataSource) {
        case DATA_SOURCE_TYPES.REMOTE:
          // 检查网络连接和服务器可达性
          return await this.checkRemoteAvailability()
        
        case DATA_SOURCE_TYPES.MOCK:
          // Mock数据总是可用的
          return true
        
        case DATA_SOURCE_TYPES.SQLITE:
          // 检查SQLite支持
          return await this.checkSqliteAvailability()
        
        default:
          return false
      }
    } catch (error) {
      console.error(`[DataSource] 检查数据源可用性失败 (${dataSource}):`, error)
      return false
    }
  }

  /**
   * 检查远程API可用性
   * @returns {Promise<boolean>}
   */
  async checkRemoteAvailability() {
    try {
      // 检查网络连接
      const networkInfo = await new Promise((resolve) => {
        uni.getNetworkType({
          success: resolve,
          fail: () => resolve({ networkType: 'none' })
        })
      })

      if (networkInfo.networkType === 'none') {
        return false
      }

      // 简单的健康检查请求
      const response = await request.get('/health', {}, {
        timeout: 5000,
        showLoading: false,
        showError: false,
        dataSource: DATA_SOURCE_TYPES.REMOTE
      })

      return response.statusCode === 200
    } catch (error) {
      return false
    }
  }

  /**
   * 检查SQLite可用性
   * @returns {Promise<boolean>}
   */
  async checkSqliteAvailability() {
    try {
      // 检查平台支持
      // #ifdef APP-PLUS
      return true
      // #endif
      
      // #ifdef H5
      // H5环境检查IndexedDB支持
      return typeof indexedDB !== 'undefined'
      // #endif
      
      // #ifdef MP
      // 小程序环境检查本地存储支持
      return typeof wx !== 'undefined' && wx.getStorageSync
      // #endif
      
      return false
    } catch (error) {
      return false
    }
  }

  /**
   * 自动选择最佳数据源
   * @returns {Promise<string>} 选择的数据源类型
   */
  async autoSelectDataSource() {
    const preferences = [
      DATA_SOURCE_TYPES.REMOTE,
      DATA_SOURCE_TYPES.SQLITE,
      DATA_SOURCE_TYPES.MOCK
    ]

    for (const dataSource of preferences) {
      const isAvailable = await this.checkDataSourceAvailability(dataSource)
      if (isAvailable) {
        this.setDataSource(dataSource)
        return dataSource
      }
    }

    // 如果都不可用，使用Mock作为后备
    this.setDataSource(DATA_SOURCE_TYPES.MOCK)
    return DATA_SOURCE_TYPES.MOCK
  }

  /**
   * 添加数据源变更监听器
   * @param {Function} listener 监听器函数
   */
  addListener(listener) {
    if (typeof listener === 'function') {
      this.listeners.push(listener)
    }
  }

  /**
   * 移除数据源变更监听器
   * @param {Function} listener 监听器函数
   */
  removeListener(listener) {
    const index = this.listeners.indexOf(listener)
    if (index > -1) {
      this.listeners.splice(index, 1)
    }
  }

  /**
   * 通知所有监听器
   * @param {Object} event 事件对象
   */
  notifyListeners(event) {
    this.listeners.forEach(listener => {
      try {
        listener(event)
      } catch (error) {
        console.error('[DataSource] 监听器执行错误:', error)
      }
    })
  }

  /**
   * 获取数据源状态信息
   * @returns {Object} 状态信息
   */
  getStatus() {
    const config = this.getDataSourceConfig()
    return {
      currentDataSource: this.currentDataSource,
      config,
      isOnline: this.currentDataSource === DATA_SOURCE_TYPES.REMOTE,
      isPersistent: config?.persistent || false,
      requiresNetwork: config?.requiresNetwork || false
    }
  }

  /**
   * 重置数据源设置
   */
  reset() {
    uni.removeStorageSync('dataSource')
    this.currentDataSource = DATA_SOURCE_TYPES.REMOTE
    request.setConfig({
      dataSource: DATA_SOURCE_TYPES.REMOTE,
      useMock: false
    })
    
    this.notifyListeners({
      type: 'dataSourceReset',
      dataSource: DATA_SOURCE_TYPES.REMOTE
    })
  }

  /**
   * 数据同步（从一个数据源同步到另一个）
   * @param {string} fromSource 源数据源
   * @param {string} toSource 目标数据源
   * @param {Object} options 同步选项
   * @returns {Promise<Object>} 同步结果
   */
  async syncData(fromSource, toSource, options = {}) {
    const {
      modules = ['users', 'habits', 'finance', 'time', 'todos'],
      overwrite = false,
      onProgress
    } = options

    const result = {
      success: true,
      synced: 0,
      failed: 0,
      errors: []
    }

    try {
      // 临时切换到源数据源
      const originalDataSource = this.currentDataSource
      this.setDataSource(fromSource, false)

      for (let i = 0; i < modules.length; i++) {
        const module = modules[i]
        
        try {
          // 从源数据源获取数据
          const data = await this.exportModuleData(module)
          
          // 切换到目标数据源
          this.setDataSource(toSource, false)
          
          // 导入数据到目标数据源
          await this.importModuleData(module, data, overwrite)
          
          result.synced++
          
          // 切换回源数据源继续下一个模块
          this.setDataSource(fromSource, false)
          
          // 通知进度
          if (onProgress) {
            onProgress({
              module,
              progress: ((i + 1) / modules.length) * 100,
              completed: i + 1,
              total: modules.length
            })
          }
        } catch (error) {
          result.failed++
          result.errors.push({
            module,
            error: error.message
          })
        }
      }

      // 恢复原始数据源
      this.setDataSource(originalDataSource, false)
      
    } catch (error) {
      result.success = false
      result.errors.push({
        module: 'general',
        error: error.message
      })
    }

    return result
  }

  /**
   * 导出模块数据
   * @param {string} module 模块名
   * @returns {Promise<Object>} 模块数据
   */
  async exportModuleData(module) {
    // 这里需要根据具体的API接口来实现
    // 简化实现，实际项目中需要调用对应的API
    const response = await request.get(`/${module}`, {
      page: 1,
      pageSize: 1000 // 获取所有数据
    })
    
    return response.data
  }

  /**
   * 导入模块数据
   * @param {string} module 模块名
   * @param {Object} data 数据
   * @param {boolean} overwrite 是否覆盖
   * @returns {Promise<void>}
   */
  async importModuleData(module, data, overwrite = false) {
    // 这里需要根据具体的API接口来实现
    // 简化实现，实际项目中需要调用对应的API
    if (overwrite) {
      // 清空现有数据
      await request.delete(`/${module}/all`)
    }
    
    // 批量导入数据
    if (data && data.length > 0) {
      await request.post(`/${module}/batch`, { items: data })
    }
  }
}

// 创建全局实例
const dataSourceManager = new DataSourceManager()

// 初始化时设置数据源
dataSourceManager.setDataSource(dataSourceManager.getCurrentDataSource())

export default dataSourceManager
export { DataSourceManager, DATA_SOURCE_CONFIG }